/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
 *
 */

import { ProjectBuildOption, TestCaseFun } from '../../plugins/task-builder/test-case';
import {
  AbilityType,
  APIType,
  APIVersion, CaseLevel,
  LanguageType, ModuleTemplateType,
  RuntimeOSType,
  SDKType
} from '../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../plugins/task-builder/task-case-builder';
import { TestTaskOptionBuilder } from '../../plugins/task-builder/test-task-option';
import {
  addDependency,
  addHarAbility,
  hasCommonElements,
  initExecuteCommand,
  runHvigorAsync, setDefaultStrictMode
} from '../../common/common';
import path from 'path';
import { ModuleJson } from '../../../../src/options/configure/module-json-options';
import { getJson5Obj } from '../../../../src/utils/json-util';
import fse from 'fs-extra';
import { expect } from '@jest/globals';
import AbilityObj = ModuleJson.AbilityObj;

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.HarmonyOS,
    apiVersion: APIVersion.API11,
    apiType: APIType.STAGE,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility
  },
  modulesOption: {
    [ModuleTemplateType.StaticLibrary]: 1
  }
};

const testfun: TestCaseFun = async (project, taskConfig, record) => {
    const projectRootPath = project.projectRootPath();
    setDefaultStrictMode(projectRootPath);
    const harRootPath = project.getModule('staticLibrary').moduleRootPath();
    await addHarAbility(harRootPath, projectRootPath);

    const command = ['assembleHar'];
    await runHvigorAsync(project.projectRootPath(), command);
    const packageHarOhPkgJsonPath = path.resolve(harRootPath, 'build/default/cache/default/default@PackageHar/oh-package.json5');
    const ohPkgJsonObj = getJson5Obj(packageHarOhPkgJsonPath);

    // 1.产物的oh-package.json的metadata/declarationEntry数组中写入由module.json/abilities/srcEntry转换得来的ohmurl
    expect(hasCommonElements(ohPkgJsonObj['metadata']['declarationEntry'], [
      '@normalized:N&&&staticLibrary/src/main/ets/components/mainpage/MainPage&1.0.0'
    ])).toBe(true);

    // 2.混淆har（产物是js中间码）.har产物的module.json/abilities/srcEntry的后缀转换成.js，字节码har则后缀换成.ts
    const releaseCommand = initExecuteCommand({
      sync: true,
      mode: 'module',
      module: 'staticLibrary',
      buildMode: 'release',
      tasks: 'assembleHar'
    });
    await runHvigorAsync(project.projectRootPath(), releaseCommand);
    const harBuildProfileFilePath = path.resolve(harRootPath, 'build-profile.json5');
    const harBuildProfileObj = getJson5Obj(harBuildProfileFilePath);
    Object.assign(harBuildProfileObj.buildOptionSet[0].arkOptions.obfuscation.ruleOptions.enable, true);
    fse.writeJSONSync(harBuildProfileFilePath, harBuildProfileObj);
    const packageHarModuleJsonPath = path.resolve(harRootPath, 'build/default/cache/default/default@PackageHar/src/main/module.json');
    const packageHarModuleJsonObj = getJson5Obj(packageHarModuleJsonPath);

    // 字节码har后缀修改为ts
    expect(packageHarModuleJsonObj.module.abilities![0].srcEntry === './ets/components/mainpage/MainPage.ts').toBe(true);

    // 源码har后缀修改为js
    Object.assign(harBuildProfileObj.buildOption, {
      arkOptions: {
        byteCodeHar: false
      }
    });
    fse.writeJSONSync(harBuildProfileFilePath, harBuildProfileObj);
    await runHvigorAsync(project.projectRootPath(), releaseCommand);
    const newPackageHarModuleJsonObj = getJson5Obj(packageHarModuleJsonPath);
    expect(newPackageHarModuleJsonObj.module.abilities![0].srcEntry === './ets/components/mainpage/MainPage.js').toBe(true);

    // 3.hap/hsp支持合并依赖har的ability
    const entryCommand = ['assembleHap'];
    Object.assign(harBuildProfileObj.buildOption, {
      'arkOptions': {
        'byteCodeHar': false
      }
    });
    fse.writeJSONSync(harBuildProfileFilePath, harBuildProfileObj);
    await addDependency(path.resolve(projectRootPath, 'entry'), { 'staticLibrary': 'file:../staticLibrary' });

    await runHvigorAsync(project.projectRootPath(), entryCommand);
    const intermediatesLoaderJsonPath = path.resolve(projectRootPath, 'entry/build/default/intermediates/loader/default/loader.json');
    const intermediatesLoaderJsonObj = getJson5Obj(intermediatesLoaderJsonPath);
    expect(intermediatesLoaderJsonObj['compileEntry'][0] === path.resolve(harRootPath, 'src/main/ets/components/mainpage/MainPage.ets')).toBe(true);

    const intermediatesPackageModuleJsonPath = path.resolve(projectRootPath, 'entry/build/default/intermediates/package/default/module.json');
    const intermediatesPackageModuleJsonObj = getJson5Obj(intermediatesPackageModuleJsonPath);
    intermediatesPackageModuleJsonObj.module.abilities.forEach((abilityObj: AbilityObj) => {
      if (abilityObj.name === 'harAbility') {
        expect(abilityObj.srcEntry === '@normalized:N&&&staticLibrary/src/main/ets/components/mainpage/MainPage&1.0.0').toBe(true);
      }
    });
  }
;

TestCaseBuilder.builder()
  .caseName('SR20240921574242')
  .description('har、hsp支持uiAbility构建')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.AR).build())
  .testFun(testfun)
  .load();

